#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>



void handler(int signo)
{
    while(true)
    {
        std::cout << "这是一个" << signo << "号信号" << std::endl;
        sleep(1);
    }
}

void Block_signal()
{
    signal(2, handler);

    // 1. 屏蔽指定信号
    sigset_t block, oblock;

    // 初始化
    sigemptyset(&block);
    sigemptyset(&oblock);

    // 添加指定信号到该信号集
    sigaddset(&block, 2);
    
    // 屏蔽操作
    sigprocmask(SIG_SETMASK, &block, &oblock);
    while(true)
    {
        std::cout << "我已经屏蔽2号信号" << std::endl;
        sleep(1);
    }
}

void PrintPending(const sigset_t &pending)
{
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending, signo))
        {
            std::cout << "1";
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << "\n";
}

void Pending_table()
{
     sigset_t set, oset;
     sigemptyset(&set);
     sigemptyset(&oset);
     sigaddset(&set, 2);
     sigprocmask(SIG_BLOCK, &set, &oset);

     // 2. 让进程不断获取当前进程的pending
     int cnt = 0;
     sigset_t pending;
     while(true)
     {
         sigpending(&pending);
         PrintPending(pending);

         sleep(1);

         cnt++;

         if(cnt == 5)
         {
             std::cout << "解除对2号信号的屏蔽, 2号信号准备递达" << std::endl;
             sigprocmask(SIG_SETMASK, &oset, nullptr);
         }
     }
}


void SigHandler()
{
    std::cout << "pid:" << getpid() << std::endl;
    // 信号的处理
    struct sigaction act, oact;
    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, 3);

    sigaction(2, &act, &oact);

    while(true)
    {
        sleep(1);
    }
}

void wait_child(int signo)
{
      std::cout << "get a signo" << signo << std::endl;

      pid_t id = 0;
      while((id = waitpid(-1, nullptr, WNOHANG)))
      {
          if(id <= 0) break;
          std::cout << "回收进程：" << id << std::endl;
      }
}

volatile int flag = 0;
int main()
{


    //通过接受信号回收子进程
    //signal(SIGCHLD, wait_child);
     
    //signal(SIGCHLD, SIG_IGN);
    //for(int i = 0; i < 10; i++)
    //{
    //    pid_t id = fork();
    //    if(id == 0)
    //    {
    //        std::cout << "child running ~" << std::endl;
    //        sleep(5);
    //        exit(10);
    //    }
    //}
    //
    return 0;
}



//volatile int flag = 0;
//
//void handler(int signo)
//{
//    std::cout << "signo: " << signo <<std::endl;
//    flag = 1;
//    std::cout << "change flag to: " << flag <<std::endl;
//}
//
//int main()
//{
//    signal(2, handler);
//    std::cout << "getpid: " << getpid() << std::endl;
//    while(!flag);
//    std::cout << "quit normal!" << std::endl;
//}
